/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

#include "IpInputControl.h"
#include <QFrame>
#include <QVBoxLayout>
#include <QRegExpValidator>
#include <QEvent>
#include <QKeyEvent>

namespace BurnDlg {

namespace {
    const int INDEX_IP_0 = 0;
    const int INDEX_IP_1 = 1;
    const int INDEX_IP_2 = 2;
    const int INDEX_IP_3 = 3;
    const int HINT_WIDTH_250 = 250;
    const int HINT_HEIGHT_20 = 20;
    const int MIN_HINT_WIDTH_30 = 30;
    const int MIN_HINT_HEIGHT_10 = 10;
    const int MAX_IP_PART_CHARACTER_NUMBER_3 = 3;
    const int MIN_IP_PART_NUMBER_100 = 100;
    const int MAX_IP_PART_NUMBER_255 = 255;
}

IpInputControl::IpInputControl(QWidget *parent)
    : QWidget(parent),
      labDot1(new QLabel()),
      labDot2(new QLabel()),
      labDot3(new QLabel()),
      textIp1(new QLineEdit),
      textIp2(new QLineEdit),
      textIp3(new QLineEdit),
      textIp4(new QLineEdit)
{
    QString bgColor = "#FFFFFF";
    QString borderColor = "#000000";

    if (labDot1 != nullptr) {
        labDot1->setAlignment(Qt::AlignCenter);
        labDot1->setText(".");
    }

    if (labDot2 != nullptr) {
        labDot2->setAlignment(Qt::AlignCenter);
        labDot2->setText(".");
    }

    if (labDot3 != nullptr) {
        labDot3->setAlignment(Qt::AlignCenter);
        labDot3->setText(".");
    }

    SetAllTextIpNameAlignSizePolTextChangeConnect();

    QString pattern = "(2[0-5]{2}|2[0-4][0-9]|1?[0-9]{1,2})";
    QRegExp regExp(pattern);
    QRegExpValidator *pReg0 = new QRegExpValidator(regExp);

    if (textIp1 != nullptr) {
        textIp1->setValidator(pReg0);
    }

    if (textIp2 != nullptr) {
        textIp2->setValidator(pReg0);
    }

    if (textIp3 != nullptr) {
        textIp3->setValidator(pReg0);
    }

    if (textIp4 != nullptr) {
        textIp4->setValidator(pReg0);
    }

    if (textIp1 != nullptr) {
        textIp1->installEventFilter(this);
    }

    if (textIp2 != nullptr) {
        textIp2->installEventFilter(this);
    }

    if (textIp3 != nullptr) {
        textIp3->installEventFilter(this);
    }

    if (textIp4 != nullptr) {
        textIp4->installEventFilter(this);
    }

    SetQFrame(bgColor);
}

bool IpInputControl::SetAllTextIpNameAlignSizePolTextChangeConnect()
{
    if (textIp1 != nullptr) {
        SetTextIpNameAlignSizePolTextChangeConnect(textIp1, "txtIP1", Qt::AlignCenter,
                                                   QSizePolicy::Expanding, QSizePolicy::Expanding);
    }

    if (textIp2 != nullptr) {
        SetTextIpNameAlignSizePolTextChangeConnect(textIp2, "txtIP2", Qt::AlignCenter,
                                                   QSizePolicy::Expanding, QSizePolicy::Expanding);
    }

    if (textIp3 != nullptr) {
        SetTextIpNameAlignSizePolTextChangeConnect(textIp3, "txtIP3", Qt::AlignCenter,
                                                   QSizePolicy::Expanding, QSizePolicy::Expanding);
    }

    if (textIp4 != nullptr) {
        SetTextIpNameAlignSizePolTextChangeConnect(textIp4, "txtIP4", Qt::AlignCenter,
                                                   QSizePolicy::Expanding, QSizePolicy::Expanding);
    }

    return true;
}

bool IpInputControl::SetTextIpNameAlignSizePolTextChangeConnect(QLineEdit *textIp, const QString &name,
                                                                Qt::Alignment flag, QSizePolicy::Policy hor,
                                                                QSizePolicy::Policy ver)
{
    if (textIp == nullptr) {
        return false;
    }

    textIp->setObjectName(name);
    textIp->setAlignment(flag);
    textIp->setSizePolicy(hor, ver);
    connect(textIp, SIGNAL(textChanged(QString)), this, SLOT(SlotTextChanged(QString)));
    return true;
}

void IpInputControl::SetQFrame(const QString &bgColor)
{
    QFrame *frame = new QFrame();
    frame->setObjectName("frameIp");
    QStringList qss;
    qss.append(QString("QLabel{min-width:15px;background-color:%1;border:none}").arg(bgColor));
    qss.append(QString("QLineEdit{background-color:%1;border:none}").arg(bgColor));
    frame->setStyleSheet(qss.join(""));
    QVBoxLayout *verticalLayout = new QVBoxLayout(this);
    verticalLayout->setContentsMargins(0, 0, 0, 0);
    verticalLayout->setSpacing(0);
    verticalLayout->addWidget(frame);
    QHBoxLayout *layout = new QHBoxLayout(frame);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    layout->addWidget(textIp1);
    layout->addWidget(labDot1);
    layout->addWidget(textIp2);
    layout->addWidget(labDot2);
    layout->addWidget(textIp3);
    layout->addWidget(labDot3);
    layout->addWidget(textIp4);
}

bool IpInputControl::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == nullptr || event == nullptr) {
        return false;
    }

    if (event->type() == QEvent::KeyPress) {
        QLineEdit *txt = dynamic_cast<QLineEdit *>(watched);
        if (txt == textIp1 || txt == textIp2 || txt == textIp3 || txt == textIp4) {
            QKeyEvent *key = dynamic_cast<QKeyEvent *>(event);
            if (key->text() == ".") {
                this->focusNextChild();
            }

            if ((key->key() == Qt::Key_Backspace) && (txt->text().length() <= 1)) {
                this->focusNextPrevChild(false);
            }
        }
    }
    return QWidget::eventFilter(watched, event);
}

void IpInputControl::SlotTextChanged(const QString &text)
{
    int len = text.length();
    int value = text.toInt();

    if (len == MAX_IP_PART_CHARACTER_NUMBER_3) {
        if (value >= MIN_IP_PART_NUMBER_100 && value <= MAX_IP_PART_NUMBER_255) {
            this->focusNextChild();
        }
    }
    ip = QString("%1.%2.%3.%4").arg(textIp1->text()).arg(textIp2->text()).arg(textIp3->text()).arg(textIp4->text());
}

QString IpInputControl::GetIP() const
{
    return this->ip;
}

QSize IpInputControl::sizeHint() const
{
    return QSize(HINT_WIDTH_250, HINT_HEIGHT_20);
}

QSize IpInputControl::minimumSizeHint() const
{
    return QSize(MIN_HINT_WIDTH_30, MIN_HINT_HEIGHT_10);
}

void IpInputControl::SetIP(const QString &ipNeedSet)
{
    QRegExp regExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
    if (!regExp.exactMatch(ipNeedSet)) {
        return;
    }
    if (this->ip != ipNeedSet) {
        this->ip = ipNeedSet;

        QStringList list = ipNeedSet.split(".");
        textIp1->setText(list.at(INDEX_IP_0));
        textIp2->setText(list.at(INDEX_IP_1));
        textIp3->setText(list.at(INDEX_IP_2));
        textIp4->setText(list.at(INDEX_IP_3));
    }
}

void IpInputControl::Clear() const
{
    textIp1->clear();
    textIp2->clear();
    textIp3->clear();
    textIp4->clear();
    textIp1->setFocus();
}

}
